package util;


import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @author 李栋
 */
public class SynchronizedTest {

    private static final Logger logger = LoggerFactory.getLogger(SynchronizedTest.class);

    /**
     * Sychornized 实现原理：
     * 底层通过一个monitor监视器锁对象完成，被synchronized修饰的代码段当它的monitor被占用时候，会处于锁定状态
     * 加锁的过程就是获取monitor锁权限的过程，0 代表monitor 没有枷锁 1代表monitor 加锁
     */

    @Test
    public void test1() {
        ThreadTest t1 = new ThreadTest("线程1");
        ThreadTest t2 = new ThreadTest("线程2");
        ThreadTest t3 = new ThreadTest("线程3");
        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();
    }

    static class ThreadTest implements Runnable {

        private final Logger logger = LoggerFactory.getLogger(SynchronizedTest.class);
        private int ticket = 20;
        private final String threadName;
        private final Object key = "";

        public ThreadTest(String name) {
            this.threadName = name;
        }

        @Override
        public void run() {
            while (ticket > 0) {
                synchronized (key) {
                    logger.info(threadName + "售出" + ticket + "张票");
                    ticket--;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    logger.info("Error Occur:{}", e.getCause());
                }
            }

        }
    }

}

